package com.hoshiicloud.gateway.util;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.hoshiicloud.auth.vo.TokenUsersVO;
import com.hoshiicloud.common.constant.TokenUserFieldEnum;
import com.hoshiicloud.common.constant.UserTypeEnum;
import com.hoshiicloud.common.utils.DigestUtils;
import com.hoshiicloud.BackSysUsersVO;
import com.hoshiicloud.common.utils.token.JWTUtil;
import io.jsonwebtoken.ExpiredJwtException;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @program: hoshiibuy
 * @description: token工具类
 * @author: Mr.wu
 * @create: 2019-06-26 15:03
 **/
@Component
public class TokenUtil {

    private static RedisTemplate redisTemplate;

    @Autowired
    public TokenUtil(RedisTemplate redisTemplate) {
        TokenUtil.redisTemplate = redisTemplate;
    }

    /**
     * 获取jwt失效时间
     */
    public static Date getExpirationDateFromToken(String token) {
        DecodedJWT jwt = JWTUtil.getDecodedJWT(token);
        return jwt.getExpiresAt();
    }

    /**
     * <pre>
     *  验证token是否失效
     *  true:过期   false:没过期
     * </pre>
     */
    public static Boolean isTokenExpired(String token) {
        try {
            final Date expiration = getExpirationDateFromToken(token);
            return expiration.before(new Date());
        } catch (ExpiredJwtException expiredJwtException) {
            return true;
        }
    }

    public static TokenUsersVO getUserInfoByJWT(String token) throws AuthenticationException {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        DecodedJWT jwt = JWTUtil.getDecodedJWT(token);
        if (jwt == null) {
            return null;
            //throw new AuthenticationException("登录信息有误");
        }
        //如果token中包含loginKey，则检查对应key是否存在
        String loginKey = jwt.getClaim(TokenUserFieldEnum.LOGIN_KEY.getName()).asString();
        if (StringUtils.isNotBlank(loginKey)) {
            String ticket = (String) redisTemplate.opsForValue().get(loginKey);
            if (StringUtils.isBlank(ticket)) {
                return null;
            }
        }

        /*
        String userName=jwt.getClaim("userName").asString();
        String platformId=jwt.getClaim("platformId").asString();
        String md5= DigestUtils.md5(platformId+userName);
        */
        TokenUsersVO userInfo = (TokenUsersVO) redisTemplate.opsForValue().get(token);
        if (userInfo == null) {
            return null;
            //throw new AuthenticationException("登录信息不存在");
        }
        //通过时延长登陆过期时间,具体策略待定
        //redisTemplate.expire(md5,1, TimeUnit.DAYS);
        //TokenUsersVO userInfo=(TokenUsersVO)obj;

        return userInfo;
    }


    public static TokenUsersVO getUserInfoByJWT2(String token) throws AuthenticationException {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        DecodedJWT jwt = JWTUtil.getDecodedJWT(token);
        if (jwt == null) {
            return null;
            //throw new AuthenticationException("登录信息有误");
        }
        String userName = jwt.getClaim(TokenUserFieldEnum.USERNAME.getName()).asString();
        String userType = jwt.getClaim(TokenUserFieldEnum.USER_TYPE.getName()).asString();
        String key = "";
        if (userType.equals(UserTypeEnum.STORE)) {
            //String storeId = jwt.getClaim(TokenUserFieldEnum.STORE_ID.getName()).asString();
            key = userType + userName;
        } else if (userType.equals(UserTypeEnum.COMPANY)) {
            String storeId = jwt.getClaim(TokenUserFieldEnum.COMPANY_ID.getName()).asString();
            key = userType + userName + storeId;
        }
        String md5 = DigestUtils.md5(key);
        Object obj = redisTemplate.opsForValue().get(md5);
        if (obj == null) {
            return null;
            //throw new AuthenticationException("登录信息不存在");
        }
        //通过时延长登陆过期时间,具体策略待定
        redisTemplate.expire(md5, 1, TimeUnit.DAYS);
        TokenUsersVO userInfo = (TokenUsersVO) obj;
        return userInfo;
    }


    /**
     * @return java.lang.String
     * @author: Mr.wu
     * @descripton: 获取当前使用用户的真实姓名
     * @date: 13:57 2019/7/1
     */
    public static String getUserRealNameByJWT() {
        Subject subject = SecurityUtils.getSubject();
        TokenUsersVO userInfo = getUserInfoByJWT(subject.getPrincipal().toString());
        return userInfo.getRealName();
    }
}
